package com.sas.repositoryImpl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.sas.repository.GenericRepository;


public class HibernateGenericRepository<T> implements GenericRepository<T> {

	private Class<T> domainClass = getDomainClass();

	private SessionFactory sessionFactory;

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	protected Class<T> getDomainClass() {
		if (domainClass == null) {
			ParameterizedType thisType = (ParameterizedType) getClass()
					.getGenericSuperclass();
			domainClass = (Class<T>) thisType.getActualTypeArguments()[0];
		}
		return domainClass;
	}

	public void delete(T obj) {
		Session session = getSession();
		session.delete(obj);
		session.flush();
	}

	@SuppressWarnings("unchecked")
	public T find(int id) {
		Session session = getSession();
		T result = (T) session.get(domainClass, id);
		return result;
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		Session session = getSession();
		List<T> result = (List<T>) session.createQuery(
				"from " + domainClass.getSimpleName()).list();
		return result;
	}
	

	/*@SuppressWarnings("unchecked")
	@Override
	public boolean exist(T obj) {
		Session session = getSession();
		Query query =  session.createQuery(
				"from " + domainClass.getSimpleName() + " obj where obj = ?");
		query.setParameter(0, obj);
		List<T> result = (List<T>) query.list();
		return !(result.size() > 0);
	}*/

	public T store(T obj) {
		Session session = getSession();
		/*if (exist(obj)) {
			return null;
		}*/
		session.save(obj);
		session.flush();

		return obj;
	}
/*	public void update(T obj) {
		Session session = getSession();
		session.update(obj);
		session.flush();
	}*/


	@SuppressWarnings("unchecked")
	public List<T> findAllSortedBy(String property, boolean ascending) {
		Session session = getSession();
		String asc = ascending ? " asc" : " desc";
		String sql = " from "+ domainClass.getName() + " order by " + property + asc;
		//String sql = " from Article art";

		List<T> result = session.createQuery(sql).list();
		
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public int size() {
		Session session = getSession();
		Query query = session.createQuery("select count (*) from " + domainClass.getName());
		List<Long> ret = query.list();
		return ret.get(0).intValue();
	}
}
